/**
 * Notes: 服务器API请求助手 (完全替代云函数)
 * Ver : WeCollege Server API 1.0.0
 * Date: 2025-01-27
 * Description: 使用自建服务器API完全替代微信云函数调用
 */

const apiConfig = require('../setting/api_config.js');
const cacheHelper = require('./cache_helper.js');
const PassportBiz = require('../comm/biz/passport_biz.js');

class ServerHelper {

  /**
   * 统一服务器API调用 (替代 callCloudSumbit)
   * @param {string} route - API路由
   * @param {object} data - 请求数据
   * @param {object} options - 选项
   * @returns {Promise<object>} 响应结果
   */
  static async callCloudSumbit(route, data = {}, options = {}) {
    return await ServerHelper.callServerSumbit(route, data, options);
  }

  /**
   * 服务器API数据调用 (替代 callCloudData)
   * @param {string} route - API路由
   * @param {object} params - 查询参数
   * @param {object} options - 选项
   * @returns {Promise<object>} 响应结果
   */
  static async callCloudData(route, params = {}, options = {}) {
    return await ServerHelper.callServerData(route, params, options);
  }

  /**
   * 异步服务器API调用 (替代 callCloudSumbitAsync)
   * @param {string} route - API路由
   * @param {object} data - 请求数据
   * @param {object} options - 选项
   * @returns {Promise<object>} 响应结果
   */
  static async callCloudSumbitAsync(route, data = {}, options = {}) {
    return await ServerHelper.callServerSumbitAsync(route, data, options);
  }

  /**
   * 通用服务器API调用 (替代 callCloud)
   * @param {string} route - API路由
   * @param {object} data - 请求数据
   * @param {object} options - 选项
   * @returns {Promise<object>} 响应结果
   */
  static async callCloud(route, data = {}, options = {}) {
    return await ServerHelper.callServer(route, data, options);
  }

  /**
   * 服务器API提交调用
   * @param {string} route - API路由
   * @param {object} data - 请求数据
   * @param {object} options - 选项
   * @returns {Promise<object>} 响应结果
   */
  static async callServerSumbit(route, data = {}, options = {}) {
    const config = ServerHelper._getRequestConfig(route, data, options);
    
    // 显示加载提示
    if (options.title && options.title !== 'bar') {
      wx.showLoading({
        title: options.title || '处理中...',
        mask: true
      });
    }

    try {
      const result = await ServerHelper._makeRequest(config);
      
      // 隐藏加载提示
      if (options.title && options.title !== 'bar') {
        wx.hideLoading();
      }

      return ServerHelper._handleResponse(result, options);
    } catch (error) {
      // 隐藏加载提示
      if (options.title && options.title !== 'bar') {
        wx.hideLoading();
      }
      
      throw error;
    }
  }

  /**
   * 服务器API数据调用
   * @param {string} route - API路由
   * @param {object} params - 查询参数
   * @param {object} options - 选项
   * @returns {Promise<object>} 响应结果
   */
  static async callServerData(route, params = {}, options = {}) {
    const config = ServerHelper._getRequestConfig(route, params, {
      ...options,
      method: 'GET'
    });

    try {
      const result = await ServerHelper._makeRequest(config);
      return ServerHelper._handleResponse(result, options);
    } catch (error) {
      throw error;
    }
  }

  /**
   * 异步服务器API调用
   * @param {string} route - API路由
   * @param {object} data - 请求数据
   * @param {object} options - 选项
   * @returns {Promise<object>} 响应结果
   */
  static async callServerSumbitAsync(route, data = {}, options = {}) {
    return await ServerHelper.callServerSumbit(route, data, {
      ...options,
      async: true
    });
  }

  /**
   * 通用服务器API调用
   * @param {string} route - API路由
   * @param {object} data - 请求数据
   * @param {object} options - 选项
   * @returns {Promise<object>} 响应结果
   */
  static async callServer(route, data = {}, options = {}) {
    return await ServerHelper.callServerSumbit(route, data, options);
  }

  /**
   * 数据列表处理 (替代 dataList)
   * @param {object} that - 页面this对象
   * @param {object} result - API响应结果
   * @param {string} listName - 列表数据名称
   * @param {object} options - 选项
   */
  static dataList(that, result, listName = 'dataList', options = {}) {
    if (!result || !result.data) {
      console.error('dataList: 无效的响应数据');
      return;
    }

    const data = result.data;
    const list = data.list || data.records || [];
    const total = data.total || data.totalCount || 0;
    const page = data.pageNo || data.current || 1;
    const size = data.pageSize || data.size || 20;

    // 处理分页数据
    let currentList = that.data[listName] || [];
    if (page === 1) {
      currentList = list;
    } else {
      currentList = currentList.concat(list);
    }

    // 更新页面数据
    const updateData = {};
    updateData[listName] = currentList;
    updateData[listName + 'Total'] = total;
    updateData[listName + 'Page'] = page;
    updateData[listName + 'Size'] = size;
    updateData[listName + 'HasMore'] = currentList.length < total;

    that.setData(updateData);

    // 停止下拉刷新
    if (wx.stopPullDownRefresh) {
      wx.stopPullDownRefresh();
    }
  }

  /**
   * 图片上传 (替代 transTempPics)
   * @param {Array<string>} tempFilePaths - 临时文件路径数组
   * @param {object} options - 选项
   * @returns {Promise<Array<string>>} 上传后的图片URL数组
   */
  static async transTempPics(tempFilePaths, options = {}) {
    return await ServerHelper.uploadImages(tempFilePaths, options);
  }

  /**
   * 单图片上传 (替代 transTempPicOne)
   * @param {string} tempFilePath - 临时文件路径
   * @param {object} options - 选项
   * @returns {Promise<string>} 上传后的图片URL
   */
  static async transTempPicOne(tempFilePath, options = {}) {
    const result = await ServerHelper.uploadImageOne(tempFilePath, options);
    return result;
  }

  /**
   * 批量图片上传
   * @param {Array<string>} tempFilePaths - 临时文件路径数组
   * @param {object} options - 选项
   * @returns {Promise<Array<string>>} 上传后的图片URL数组
   */
  static async uploadImages(tempFilePaths, options = {}) {
    if (!tempFilePaths || tempFilePaths.length === 0) {
      return [];
    }

    const uploadPromises = tempFilePaths.map(filePath => 
      ServerHelper.uploadImageOne(filePath, options)
    );

    try {
      const results = await Promise.all(uploadPromises);
      return results.filter(url => url); // 过滤掉失败的上传
    } catch (error) {
      console.error('批量图片上传失败:', error);
      throw error;
    }
  }

  /**
   * 单图片上传
   * @param {string} tempFilePath - 临时文件路径
   * @param {object} options - 选项
   * @returns {Promise<string>} 上传后的图片URL
   */
  static async uploadImageOne(tempFilePath, options = {}) {
    if (!tempFilePath) {
      throw new Error('图片路径不能为空');
    }

    const config = apiConfig.getConfig();
    const token = PassportBiz.getToken();

    return new Promise((resolve, reject) => {
      wx.uploadFile({
        url: `${config.baseURL}/upload/image`,
        filePath: tempFilePath,
        name: 'file',
        header: {
          'Authorization': token ? `Bearer ${token}` : ''
        },
        formData: {
          type: options.type || 'common'
        },
        success: (res) => {
          try {
            const data = JSON.parse(res.data);
            if (data.code === 200 && data.data && data.data.url) {
              resolve(data.data.url);
            } else {
              reject(new Error(data.message || '图片上传失败'));
            }
          } catch (error) {
            reject(new Error('图片上传响应解析失败'));
          }
        },
        fail: (error) => {
          console.error('图片上传失败:', error);
          reject(error);
        }
      });
    });
  }

  /**
   * 获取请求配置
   * @param {string} route - API路由
   * @param {object} data - 请求数据
   * @param {object} options - 选项
   * @returns {object} 请求配置
   */
  static _getRequestConfig(route, data, options) {
    const config = apiConfig.getConfig();
    const token = PassportBiz.getToken();
    
    // 路由映射
    const mappedRoute = ServerHelper._mapRoute(route);
    
    return {
      url: `${config.baseURL}/${mappedRoute}`,
      method: options.method || 'POST',
      data: data,
      header: {
        'Content-Type': 'application/json',
        'Authorization': token ? `Bearer ${token}` : '',
        ...options.header
      },
      timeout: options.timeout || config.timeout
    };
  }

  /**
   * 发起网络请求
   * @param {object} config - 请求配置
   * @returns {Promise<object>} 响应结果
   */
  static _makeRequest(config) {
    return new Promise((resolve, reject) => {
      wx.request({
        ...config,
        success: (res) => {
          resolve(res);
        },
        fail: (error) => {
          console.error('网络请求失败:', error);
          reject(error);
        }
      });
    });
  }

  /**
   * 处理响应结果
   * @param {object} response - 原始响应
   * @param {object} options - 选项
   * @returns {object} 处理后的结果
   */
  static _handleResponse(response, options) {
    if (response.statusCode !== 200) {
      throw new Error(`HTTP ${response.statusCode}: ${response.data}`);
    }

    let data;
    try {
      data = typeof response.data === 'string' ? JSON.parse(response.data) : response.data;
    } catch (error) {
      throw new Error('响应数据解析失败');
    }

    // 统一响应格式处理
    if (data.code !== 200) {
      const errorMsg = data.message || '请求失败';
      
      // 显示错误提示
      if (options.showError !== false) {
        wx.showToast({
          title: errorMsg,
          icon: 'none',
          duration: 2000
        });
      }
      
      throw new Error(errorMsg);
    }

    return {
      code: data.code,
      data: data.data,
      message: data.message || 'success'
    };
  }

  /**
   * 路由映射 (云函数路由 -> 服务器API路由)
   * @param {string} route - 原始路由
   * @returns {string} 映射后的路由
   */
  static _mapRoute(route) {
    const routeMap = {
      // 用户相关
      'passport/login': 'user/login',
      'passport/register': 'user/register',
      'passport/my_detail': 'user/profile',
      'passport/edit_base': 'user/updateProfile',
      'passport/phone': 'user/getPhone',
      
      // 帖子相关 (表白墙、兼职、失物、请假都映射到帖子API)
      'board/insert': 'post/insert',
      'board/edit': 'post/update',
      'board/detail': 'post/getSingle',
      'board/view': 'post/visit',
      'board/like': 'post/like',
      'board/list': 'post/query',
      'board/del': 'post/delete',
      'board/status': 'post/status',
      
      'job/insert': 'post/insert',
      'job/edit': 'post/update',
      'job/detail': 'post/getSingle',
      'job/view': 'post/visit',
      'job/like': 'post/like',
      'job/list': 'post/query',
      'job/del': 'post/delete',
      'job/status': 'post/status',
      
      'lost/insert': 'post/insert',
      'lost/edit': 'post/update',
      'lost/detail': 'post/getSingle',
      'lost/view': 'post/visit',
      'lost/like': 'post/like',
      'lost/list': 'post/query',
      'lost/del': 'post/delete',
      'lost/status': 'post/status',
      
      'leave/insert': 'post/insert',
      'leave/edit': 'post/update',
      'leave/detail': 'post/getSingle',
      'leave/view': 'post/visit',
      'leave/like': 'post/like',
      'leave/list': 'post/query',
      'leave/del': 'post/delete',
      'leave/status': 'post/status',
      
      // 评论相关
      'comment/insert': 'comment/insert',
      'comment/del': 'comment/delete',
      'comment/like': 'comment/like',
      'comment/list': 'comment/queryByPost',
      
      // 新闻相关
      'news/detail': 'news/getSingle',
      'news/view': 'news/visit',
      'news/list': 'news/query',
      
      // 管理员相关
      'admin/login': 'admin/login',
      'admin/user_list': 'admin/user/list',
      'admin/user_del': 'admin/user/delete',
      'admin/user_status': 'admin/user/status',
      'admin/user_detail': 'admin/user/detail',
      'admin/user_data_get': 'admin/user/export/data',
      'admin/user_data_export': 'admin/user/export/excel',
      'admin/user_data_del': 'admin/user/export/clear',
      
      'admin/mgr_insert': 'admin/manager/insert',
      'admin/mgr_edit': 'admin/manager/update',
      'admin/mgr_del': 'admin/manager/delete',
      'admin/mgr_status': 'admin/manager/status',
      'admin/mgr_detail': 'admin/manager/detail',
      'admin/mgr_pwd': 'admin/manager/password',
      'admin/log_clear': 'admin/log/clear',
      
      'admin/news_insert': 'admin/news/insert',
      'admin/news_edit': 'admin/news/update',
      'admin/news_del': 'admin/news/delete',
      'admin/news_status': 'admin/news/status',
      'admin/news_detail': 'admin/news/detail',
      'admin/news_sort': 'admin/news/sort',
      'admin/news_vouch': 'admin/news/vouch',
      
      'admin/board_del': 'admin/post/delete',
      'admin/board_status': 'admin/post/status',
      'admin/board_sort': 'admin/post/sort',
      'admin/board_data_get': 'admin/post/export/data',
      'admin/board_data_export': 'admin/post/export/excel',
      'admin/board_data_del': 'admin/post/export/clear',
      
      'admin/job_del': 'admin/post/delete',
      'admin/job_status': 'admin/post/status',
      'admin/job_sort': 'admin/post/sort',
      'admin/job_data_get': 'admin/post/export/data',
      'admin/job_data_export': 'admin/post/export/excel',
      'admin/job_data_del': 'admin/post/export/clear',
      
      'admin/lost_del': 'admin/post/delete',
      'admin/lost_status': 'admin/post/status',
      'admin/lost_sort': 'admin/post/sort',
      'admin/lost_data_get': 'admin/post/export/data',
      'admin/lost_data_export': 'admin/post/export/excel',
      'admin/lost_data_del': 'admin/post/export/clear',
      
      'admin/leave_del': 'admin/post/delete',
      'admin/leave_status': 'admin/post/status',
      'admin/leave_sort': 'admin/post/sort',
      'admin/leave_data_get': 'admin/post/export/data',
      'admin/leave_data_export': 'admin/post/export/excel',
      'admin/leave_data_del': 'admin/post/export/clear',
      
      'admin/home': 'admin/dashboard',
      'admin/clear_vouch': 'admin/clearVouch',
      'admin/setup_qr': 'admin/setup/qr',
      
      // 收藏相关
      'fav/update': 'favorite/toggle',
      'fav/is_fav': 'favorite/check',
      'fav/del': 'favorite/delete',
      
      // 首页相关
      'home/list': 'home/data',
      'home/setup_get': 'common/setup',
      
      // 内容检查
      'check/img': 'common/imageCheck'
    };

    return routeMap[route] || route;
  }
}

// 兼容性导出
module.exports = ServerHelper;